﻿using System;
using System.Linq;
using FakeItEasy;
using NJabber.Stream.Elements;
using NUnit.Framework;

namespace NJabber.Client
{
    [TestFixture]
    public class IqStanzaHandlerTests
    {
        private RosterCache rosterCache;
        private IqStanzaHandler handler;

        [SetUp]
        public void Setup()
        {
            rosterCache = new RosterCache(A.Fake<IRosterSynchronizer>());
            handler = new IqStanzaHandler(rosterCache);
        }

        [Test]
        [ExpectedException(typeof (ArgumentNullException))]
        public void ProcessStanza_StanzaValueIsNull_ThrowsException()
        {
            handler.ProcessStanza(A.Fake<StandartClientRuntime>(), null);
        }

        [Test]
        [ExpectedException(typeof (ArgumentNullException))]
        public void Constructor_NullParameter_ThrowsException()
        {
            handler = new IqStanzaHandler(null);
        }

        [Test]
        public void ProcessStanza_RosterResultStanza_FillsRosterChacheWithItems()
        {
            RosterItem[] rosterItems = CreateRosterItems(4);
            IqStanza stanza = CreateRoserResult(rosterItems);

            handler.ProcessStanza(null, stanza);

            CollectionAssert.AreEquivalent(rosterItems, rosterCache.Items);
        }

        private RosterItem[] CreateRosterItems(int count)
        {
            return Enumerable.Range(0, count)
                             .Select(i => new RosterItem("item" + i, i + "@xmpp.org"))
                             .ToArray();
        }

        private IqStanza CreateRoserResult(RosterItem[] rosterItems)
        {
            IqStanza rosterResult = new IqStanza(IqStanzaTypes.Result);
            IqQueryElement query = rosterResult.AddQueryElement(XmppNamespaces.Roster);
            foreach (RosterItem item in rosterItems) query.AddRosterItem(item.Name, item.Jid);
            
            return rosterResult;
        }

        [Test]
        public void ProcessStanza_RosterPushStanza_PushItemIntoCache()
        {
            RosterItem item = new RosterItem("item", "item.jabber.org");
            IqStanza stanza = CreateRosterItemPushStanza(item);

            handler.ProcessStanza(null, stanza);

            CollectionAssert.Contains(rosterCache.Items, item);
            CollectionAssert.IsEmpty(rosterCache.AddedItems);
            CollectionAssert.IsEmpty(rosterCache.RemovedItems);
        }

        private IqStanza CreateRosterItemPushStanza(RosterItem item)
        {
            IqStanza stanza = new IqStanza(IqStanzaTypes.Set);
            IqQueryElement query = stanza.AddQueryElement(XmppNamespaces.Roster);
            query.AddRosterItem(item.Name, item.Jid);
            return stanza;
        }
    }
}
